package com.ymy.thinking.in.spring.bean.definition;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import thinking.in.spring.ioc.overview.domain.User;

import java.util.Map;

/**
 * Java API 注册 {@link org.springframework.beans.factory.config.BeanDefinition} 到 IoC 容器
 *
 * @author Ringo
 * @date 2021/8/24 22:22
 */
public class JavaAPIRegistryBeanDefinitionDemo {

    public static void main(String[] args) {
        // 创建 IoC 容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.scan("com.ymy.thinking.in.spring.bean.definition.**");
        // 命名注册
        registerBeanDefinition(applicationContext, "zs-user");
        // 非命名注册
        registerBeanDefinition(applicationContext);

        // 开启 Spring 应用上下文
        applicationContext.refresh();

        // 依赖查找
        Map<String, User> users = applicationContext.getBeansOfType(User.class);
        System.out.println("IoC 容器中所有 User 类型的 Bean: ");
        users.forEach((k, v) -> System.out.println(k + "=" + v));

        // 关闭 Spring 应用上下文
        applicationContext.close();
    }

    // 命名方式 注册
    public static void registerBeanDefinition(BeanDefinitionRegistry registry, String beanName) {
        BeanDefinitionBuilder builder = BeanDefinitionBuilder
                .genericBeanDefinition(User.class)
                .addPropertyValue("id", 3500L)
                .addPropertyValue("name", "张三");
        AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
        if (StringUtils.hasText(beanName)) {
            // 命名注册
            registry.registerBeanDefinition(beanName, beanDefinition);
        } else {
            // 非命名注册
            BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinition, registry);
        }
    }

    // 非命名方式 注册
    public static void registerBeanDefinition(BeanDefinitionRegistry registry) {
        registerBeanDefinition(registry, null);
    }

    // 配置方式 注册
    @Configuration
    public static class Config {
        @Bean(name = "lisi-user")
        public User user() {
            User user = new User();
            user.setName("里斯");
            user.setId(89L);
            return user;
        }
    }

}
